﻿using System;
using System.Drawing;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.SqlClient;
using BolsaTalentos.DataContextClasses;

namespace BolsaTalentos.BLL
{
    public class UsuarioEgresado : BolsaTalentos.BLL.UsuarioAplicacion
    {
        // Campos
        private string matricula;
        private string estado;
        private string primerNombre;
        private string segundoNombre;
        private string primerApellido;
        private string segundoApellido;
        private Carrera carrera;
        private DateTime fechaNacimiento;
        private int edad;
        private string sexo;
        private int experienciaLaboral;
        private string detalleExperienciaLaboral;
        private string intereses;
        private bool siVehiculoPropio;
        private bool siBuscaTiempoCompleto;
        private Image foto;
        //private Ficha ficha;
        private List<Aplicacion> aplicaciones;
        private List<Contacto> contactos;
        private List<Habilidad> habilidades;

        // Propiedades
        public string Matricula
        {
            get { return this.matricula; }
        }
        public string Estado
        {
            get { return this.estado; }
            set { this.estado = value.Trim(); }
        }
        public string PrimerNombre // Esta propiedad deberia ser ReadOnly
        {
            get { return this.primerNombre; }
            set { this.primerNombre = value.Trim(); }
        }
        public string SegundoNombre // Esta propiedad deberia ser ReadOnly
        {
            get { return this.segundoNombre; }
            set { this.segundoNombre = value.Trim(); }
        }
        public string PrimerApellido // Esta propiedad deberia ser ReadOnly
        {
            get { return this.primerApellido; }
            set { this.primerApellido = value.Trim(); }
        }
        public string SegundoApellido // Esta propiedad deberia ser ReadOnly
        {
            get { return this.segundoApellido; }
            set { this.segundoApellido = value.Trim(); }
        }
        public string Nombres
        {
            get { return (this.primerNombre + " " + this.segundoNombre).Trim(); }
        }
        public string Apellidos
        {
            get { return (this.primerApellido + " " + this.segundoApellido).Trim(); }
        }
        public string NombreCompleto
        {
            get { return (this.Nombres + " " + this.Apellidos).Trim(); }
        }
        public Carrera Carrera
        {
            get
            {
                if (this.carrera == null)
                {
                    this.carrera = Carrera.GetCarreraByUsuarioEgresadoID(this.ID);
                }
                return this.carrera;
            }
        }
        public DateTime FechaNacimiento
        {
            get { return this.fechaNacimiento; }
        }
        public int Edad
        {
            get { return this.edad; }
        }
        public string Sexo
        {
            get { return this.sexo; }
        }
        public int AñosDeExperienciaLaboral
        {
            get { return this.experienciaLaboral; }
            set { this.experienciaLaboral = value; }
        }
        public string DetalleExperienciaLaboral
        {
            get { return this.detalleExperienciaLaboral; }
            set { this.detalleExperienciaLaboral = value.Trim(); }
        }
        public string Intereses
        {
            get { return this.intereses; }
            set { this.intereses = value.Trim(); }
        }
        public bool SiVehiculoPropio
        {
            get { return this.siVehiculoPropio; }
            set { this.siVehiculoPropio = value; }
        }
        public bool SiBuscaTiempoCompleto
        {
            get { return this.siBuscaTiempoCompleto; }
            set { this.siBuscaTiempoCompleto = value; }
        }
        public Image Foto
        {
#warning Cambiar a lazy load cuando las clases de Linq esten implementadas
            get { return this.foto; }
            set { this.foto = value; }
        }
        public List<Aplicacion> Aplicaciones
        {
            get
            {
                if (this.aplicaciones == null)
                {
                    this.aplicaciones = Aplicacion.GetAplicacionesByUserID(this.ID);
                }
                return this.aplicaciones;
            }
            set { this.aplicaciones = value; }
        }
        public List<Contacto> Contactos
        {
            get
            {
                if (this.contactos == null)
                {
                    this.contactos = Contacto.GetContactosByEgresadoID(this.ID);
                }
                return this.contactos;
            }
            set { this.contactos = value; }
        }
        public List<Habilidad> Habilidades
        {
            get
            {
                if (this.habilidades == null)
                {
                    this.habilidades = Habilidad.GetHabilidadesByEgresado(this.ID);
                }
                return this.habilidades;
            }
            set { this.habilidades = value; }
        }

        // Constructores
        public UsuarioEgresado(int IDToSearch)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();

                DataContextClasses.Egresado Egr = (from e in DB.Egresados
                                                   where (e.ID == IDToSearch)
                                                   select e).First();

                this.id = Egr.ID;
                this.userName = Egr.Matricula;
                this.passWord = Egr.PassWord;
                this.matricula = Egr.Matricula;
                this.estado = Egr.Estado;
                this.primerNombre = Egr.PrimerNombre;
                this.segundoNombre = Egr.SegundoNombre;
                this.primerApellido = Egr.PrimerApellido;
                this.segundoApellido = Egr.SegundoApellido;
                //this.carrera = Egr.Carrera.Carrera.Descripcion;
                this.fechaNacimiento = Egr.FechaNacimiento;
                this.edad = ((DateTime.Now.Subtract(Egr.FechaNacimiento).Days) / 365);
                this.fechaPrimerIngreso = Egr.FechaPrimerIngreso;
                this.fechaUltimoIngreso = Egr.FechaUltimoIngreso;
                this.sexo = Egr.Sexo.ToString();
                this.experienciaLaboral = Egr.ExperienciaLaboral;
                this.detalleExperienciaLaboral = Egr.DetalleExperienciaLaboral;
                this.intereses = Egr.Intereses;
                this.siVehiculoPropio = Egr.SiVehiculoPropio;
                this.siBuscaTiempoCompleto = Egr.SiBuscaTiempoCompleto;
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("No existe tal usuario\n" + SqlEx.Message);
            }
        }
        public UsuarioEgresado(string UserNameToLog, string PassWordToLog)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();

                DataContextClasses.Egresado Egr = (from e in DB.Egresados
                                                   where (e.Matricula == UserNameToLog) && (e.PassWord == PassWordToLog)
                                                   select e).First();

                this.id = Egr.ID;
                this.userName = Egr.Matricula;
                this.passWord = Egr.PassWord;
                this.matricula = Egr.Matricula;
                this.estado = Egr.Estado;
                this.primerNombre = Egr.PrimerNombre;
                this.segundoNombre = Egr.SegundoNombre;
                this.primerApellido = Egr.PrimerApellido;
                this.segundoApellido = Egr.SegundoApellido;
                //this.carrera = Egr.Carrera.Descripcion;
                this.fechaNacimiento = Egr.FechaNacimiento;
                this.edad = ((DateTime.Now.Subtract(Egr.FechaNacimiento).Days) /365);
                this.fechaPrimerIngreso = Egr.FechaPrimerIngreso;
                this.fechaUltimoIngreso = Egr.FechaUltimoIngreso;
                this.sexo = Egr.Sexo.ToString();
                this.experienciaLaboral = Egr.ExperienciaLaboral;
                this.detalleExperienciaLaboral = Egr.DetalleExperienciaLaboral;
                this.intereses = Egr.Intereses;
                this.siVehiculoPropio = Egr.SiVehiculoPropio;
                this.siBuscaTiempoCompleto = Egr.SiBuscaTiempoCompleto;
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("No existe tal usuario o su username o password estan mal escritos\n" + SqlEx.Message);
            }
        }

        // Metodos
        public void Insertar()
        {
            DataClassesDataContext DB = new DataClassesDataContext();

            try
            {
                DataContextClasses.Egresado UsuarioEgrToInsert = new DataContextClasses.Egresado();

                UsuarioEgrToInsert.ID = this.id;
                UsuarioEgrToInsert.Matricula = this.userName;
                UsuarioEgrToInsert.PassWord = this.passWord;
                UsuarioEgrToInsert.Matricula = this.matricula;
                UsuarioEgrToInsert.Estado = this.estado;
                UsuarioEgrToInsert.PrimerNombre = this.primerNombre;
                UsuarioEgrToInsert.SegundoNombre = this.segundoNombre;
                UsuarioEgrToInsert.PrimerApellido = this.primerApellido;
                UsuarioEgrToInsert.SegundoApellido = this.segundoApellido;
                UsuarioEgrToInsert.ID_Carrera = this.Carrera.ID;
                //UsuarioEgrToInsert.ID_Carrera = Carrera.GetCarreraByUsuarioEgresadoID(this.id).ID;
                UsuarioEgrToInsert.FechaNacimiento = this.fechaNacimiento;
                UsuarioEgrToInsert.Sexo = this.sexo[0];              
                UsuarioEgrToInsert.ExperienciaLaboral = this.experienciaLaboral;
                UsuarioEgrToInsert.DetalleExperienciaLaboral = this.detalleExperienciaLaboral;
                UsuarioEgrToInsert.Intereses = this.intereses;
                UsuarioEgrToInsert.SiVehiculoPropio = this.siVehiculoPropio;
                UsuarioEgrToInsert.SiBuscaTiempoCompleto = this.siBuscaTiempoCompleto;

                DB.Egresados.InsertOnSubmit(UsuarioEgrToInsert);

                DB.SubmitChanges();
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("Hubo un problema con la base de datos\n" + SqlEx.Message);
            }
        }
        public void InsertarRelaciones()
        {
            bool YaEstaRelacionada;

            DataClassesDataContext DB = new DataClassesDataContext();

            var HabilidadesRelacionadas = (from v in DB.Egresados_Habilidades
                                           where v.ID_Egresado == this.id
                                           select v);

            List<Habilidad> HabilidadesARelacionar = new List<Habilidad>();

            foreach (Habilidad Habilidad in this.Habilidades)
            {
                YaEstaRelacionada = false;
                foreach (var item in HabilidadesRelacionadas)
                {
                    if (Habilidad.ID == item.ID_Habilidad) YaEstaRelacionada = true;
                }
                if (YaEstaRelacionada == false) HabilidadesARelacionar.Add(Habilidad);
            }

            try
            {
                foreach (var item in HabilidadesARelacionar)
                {
                    DataContextClasses.Egresados_Habilidade RelacionEgresado_Habilidad = new DataContextClasses.Egresados_Habilidade();

                    RelacionEgresado_Habilidad.ID_Egresado = this.ID;
                    RelacionEgresado_Habilidad.ID_Habilidad = item.ID;

                    DB.Egresados_Habilidades.InsertOnSubmit(RelacionEgresado_Habilidad);

                    DB.SubmitChanges();
                }
            }
            catch (Exception ex)
            {
#warning Recuerda cambiar este WriteLine por una exception
                Console.WriteLine("Hubo un problema con la Base de datos\n" + ex.Message);
                //throw new SystemExceptions.InvalidUserException("No existe tal usuario o su username o password estan mal escritos\n" + InvOperEx.Message);
            }
        }
        public void Actualizar()
        {
            DataClassesDataContext DB = new DataClassesDataContext();
            try
            {
                DataContextClasses.Egresado UsuarioEgr = (from e in DB.Egresados
                                                          where e.ID == this.id
                                                          select e).First();

                UsuarioEgr.ID = this.id;
                UsuarioEgr.Matricula = this.userName;
                UsuarioEgr.PassWord = this.passWord;
                UsuarioEgr.Matricula = this.matricula;
                UsuarioEgr.Estado = this.estado;
                UsuarioEgr.PrimerNombre = this.primerNombre;
                UsuarioEgr.SegundoNombre = this.segundoNombre;
                UsuarioEgr.PrimerApellido = this.primerApellido;
                UsuarioEgr.SegundoNombre = this.segundoNombre;
                UsuarioEgr.ID_Carrera = this.Carrera.ID;
                //UsuarioEgrToInsert.FechaNacimiento = this.fechaNacimiento;
                UsuarioEgr.FechaPrimerIngreso = this.fechaPrimerIngreso;
                UsuarioEgr.FechaUltimoIngreso = this.fechaUltimoIngreso;
                UsuarioEgr.Sexo = this.sexo[0];
                UsuarioEgr.ExperienciaLaboral = this.experienciaLaboral;
                UsuarioEgr.DetalleExperienciaLaboral = this.detalleExperienciaLaboral;
                UsuarioEgr.Intereses = this.intereses;
                UsuarioEgr.SiVehiculoPropio = this.siVehiculoPropio;
                UsuarioEgr.SiBuscaTiempoCompleto = this.siBuscaTiempoCompleto;

                DB.SubmitChanges();
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("Hubo un problema con la base de datos\n" + SqlEx.Message);
            }
        }

        public static UsuarioEgresado GetAplicanteByAplicacionID(int AplicacionID)
        {
            DataClassesDataContext DB = new DataClassesDataContext();

            DataContextClasses.Aplicacione Apl = (from a in DB.Aplicaciones
                                                   where a.ID == AplicacionID
                                                   select a).First();

            UsuarioEgresado Aplicante = new UsuarioEgresado(Apl.ID_Egresado);
            return Aplicante;
        }
        /*public int EdadEgresado(int IDToSearch)
        {
            DataClassesDataContext DB = new DataClassesDataContext();

            DataContextClasses.Egresado Egr = (from e in DB.Egresados
                                               where (e.ID == IDToSearch)
                                               select e).First();
            
        }*/
        public void AplicarAVacante(int VacanteID, string ComentarioDeAplicacion)
        {
            try
            {
                Aplicacion AplicacionToSubmit = new Aplicacion(VacanteID, this.id, ComentarioDeAplicacion);
                AplicacionToSubmit.Insertar();
            }
            catch (Exception Ex)
            {
                throw new Exception("Esta aplicacion ya existe\n" + Ex.Message);
            }
        }
        public void DesactivarAplicacion(int AplicacionID)
        {
            try
            {
                Aplicacion AplicacionToDeactivate = (from atd in this.Aplicaciones
                                                     where atd.ID == AplicacionID
                                                     select atd).First();

                AplicacionToDeactivate.ToggleActivation();
            }
            catch (Exception Ex)
            {
                throw Ex;
            }
        }
        public void ActivarAplicacion(int AplicacionID)
        {
            Aplicacion AplicacionToActivate = (from atd in this.Aplicaciones
                                                 where atd.ID == AplicacionID
                                                 select atd).First();

            if (AplicacionToActivate.VacanteAplicada.SiActiva)
            {
                AplicacionToActivate.ToggleActivation();
                return;
            }
            else 
            {
                throw new Exception("Esta aplicacion no se puede activar porque la vacante a la que estaba asociada ya no existe");
            }
        }
        public void AgregarHabilidad(int HabilidadID)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();
                Egresados_Habilidade HabilidadToAdd = new Egresados_Habilidade();

                HabilidadToAdd.ID_Habilidad = HabilidadID;
                HabilidadToAdd.ID_Egresado = this.id;

                DB.Egresados_Habilidades.InsertOnSubmit(HabilidadToAdd);
                DB.SubmitChanges();

                this.habilidades = null;
            }
            catch (SqlException)
            {
                throw new Exception("Esta habilidad no se puede agregar, ya pertenece a este egresado");
            }
        }
        public void EliminarHabilidad(int HabilidadID)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();

                Egresados_Habilidade HabilidadToDelete = (from e_h in DB.Egresados_Habilidades
                                                          where e_h.ID_Habilidad == HabilidadID && e_h.ID_Egresado == this.id
                                                          select e_h).First();

                DB.Egresados_Habilidades.DeleteOnSubmit(HabilidadToDelete);
                DB.SubmitChanges();

                this.habilidades = null;
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("Error en la base de datos. Intente en unos minutos" + SqlEx.Message);
            }
        }
        public void AgregarContacto(int TipoContactoID, string ContactoDescripcion)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();
                DataContextClasses.Contacto ContactoToAdd = new DataContextClasses.Contacto();

                ContactoToAdd.ID_TipoContacto = TipoContactoID;
                ContactoToAdd.TipoUsuario = "Egresado";
                ContactoToAdd.ID_Usuario = this.id;
                ContactoToAdd.Contacto1 = ContactoDescripcion;

                DB.Contactos.InsertOnSubmit(ContactoToAdd);
                DB.SubmitChanges();

                this.contactos = null;
            }
            catch (SqlException)
            {
                throw new Exception("Este contacto no se puede agregar, ya existe en la base de datos");
            }
        }
        public void EliminarContacto(int ContactoID)
        {
            try
            {
                DataClassesDataContext DB = new DataClassesDataContext();

                DataContextClasses.Contacto ContactoToDelete = (from c in DB.Contactos
                                                                 where c.ID == ContactoID
                                                                 select c).First();

                DB.Contactos.DeleteOnSubmit(ContactoToDelete);
                DB.SubmitChanges();

                this.contactos = null;
            }
            catch (SqlException SqlEx)
            {
                throw new Exception("Error en la base de datos. Intente en unos minutos" + SqlEx.Message);
            }
        }
    }
}